const fs = require('fs')
const promisify = require('util').promisify
const stat = promisify(fs.stat)
const readdir = promisify(fs.readdir)
const path = require('path')
const Handlebars = require('handlebars')
const config = require('./defaultConfig')
const mime= require('./mime')
const compress = require('./compress')
const range = require('./range')
const isFresh = require('./cache')

const tplPath = path.join(__dirname, '../template/dir.tpl')
const suorce = fs.readFileSync(tplPath)
const template = Handlebars.compile(suorce.toString())

module.exports = async function (req, res, filePath) {
  try {
    const stats = await stat(filePath)
    if(stats.isFile()) {
      const contentType = mime(filePath)
      res.setHeader('Content-type', contentType.text)
      if(isFresh(stats, req, res)) {
        res.statusCode = 304
        res.end()
        return
      }
      let rs;
      const {code, start, end} = range(stats.size, req, res)
      if(code == 200) {
        res.statusCode = 200
        rs = fs.createReadStream(filePath)
      }else{
        res.statusCode = 206
        rs = fs.createReadStream(filePath, {start, end})
      }
      if(filePath.match(config.compress)) {
        rs = compress(rs, req, res)
      }
      rs.pipe(res)
    }else{
      const files = await readdir(filePath)
      res.statusCode = 200
      res.setHeader('Content-type', 'text/html')
      const dir = path.relative(config.root, filePath)
      const data = {
        title: path.basename(filePath),
        files: files.map(file => {
          return {
            file,
            icon: mime(file).icon
          }
        }),
        dir: !dir || dir === '/' ? '' : `/${dir}`
      }
      res.end(template(data))
    }
  } catch (err) {
    console.error(err);
    res.statusCode = 404
    res.setHeader('Conent-type', 'text/plain')
    res.end(`404${err.toString()}`)
  }
}